package pl.edu.pw.ee.buildcity.scheduler;

import org.fest.assertions.Fail;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.JobExecutionException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pl.edu.pw.ee.buildcity.commons.Const;
import pl.edu.pw.ee.buildcity.dao.GenericDao;
import pl.edu.pw.ee.buildcity.entities.BuildActivity;
import pl.edu.pw.ee.buildcity.entities.BuildDefinition;
import pl.edu.pw.ee.buildcity.scheduler.api.BuildCityScheduler;
import pl.edu.pw.ee.buildcity.scm.subversion.SVNCheckoutParameters;
import pl.edu.pw.ee.buildcity.scm.subversion.SubversionService;
import pl.edu.pw.ee.buildcity.services.BuildDefinitionService;

import javax.annotation.Resource;
import javax.persistence.EntityNotFoundException;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.fest.assertions.Assertions.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:scheduler-context.xml", "classpath:test-context.xml"})
public class BuildJobIntegrationTestCase {

	@Resource(name = "buildCityScheduler")
	private BuildCityScheduler buildCityScheduler;

	@Resource(name = "buildDefinitionService")
	private BuildDefinitionService buildDefinitionService;

	@Resource(name = "jpaGenericDao")
	private GenericDao<BuildActivity, String> buildActivityDao;

	@Resource(name = "subversionService")
	private SubversionService subversionService;

	private static final String TEST_PROJECT = "http://buildcity.googlecode.com/svn/trunk/wordcounter";

	@After
	public void flushDB() {
		for (BuildActivity activityToRemove : buildActivityDao.executeQuery("from BuildActivity")) {
			buildActivityDao.remove(activityToRemove);
		}
		for (BuildDefinition buildDefinition : buildDefinitionService.getAll()) {
			buildDefinitionService.delete(buildDefinition);
		}
	}

	@Test
	public void shouldInjectServicesWhenRunningJobByQuartz() throws JobExecutionException, InterruptedException {
		// Given
		BuildCityJobDetail buildCityJobDetail = new BuildCityJobDetail("myJob");
		buildCityScheduler.save(buildCityJobDetail);

		BuildDefinition buildDefinition = new BuildDefinition();
		buildDefinition.setForceCleanBuild(false);
		buildDefinition.setName("myJob");
		buildDefinition.setRepositoryURL(TEST_PROJECT);
		buildDefinition.setWorkingCopy(getWorkingCopyURI());
		buildDefinitionService.persist(buildDefinition);

		// When
		buildCityScheduler.fireNow("myJob");

		// Then
		Thread.currentThread().sleep(20 * 1000);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", "myJob");
		try {
			List<BuildActivity> buildActivities = buildActivityDao.executeNamedQuery("findAllBuildActivitiesOfBuildDefinition", params);
			Fail.fail("EntityNotFoundException should be thrown as HEAD revision not changed, and so not activity is registered!");
		} catch (Exception e) {
			assertThat(e).isInstanceOf(EntityNotFoundException.class);
		}
	}

	private String getWorkingCopyURI() {
		SVNCheckoutParameters parameters = SVNCheckoutParameters.checkoutHEAD(TEST_PROJECT);
		File workingCopy = subversionService.checkout(parameters, Const.WORKING_COPIES + "/wordcounter");
		return workingCopy.getAbsolutePath();
	}
}
